package com.game.logic.netty;

import com.game.framework.message.event.GameMessageHandler;
import com.game.framework.message.event.GameMessageMapping;
import com.game.framework.message.event.GameMessageMetaData;
import com.game.framework.message.event.IGameMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class RequestHandlerContext {

	private ApplicationContext applicationContext;
	private Map<Integer, Class<? extends IGameMessage>> gameMessageClassMap = new HashMap<>();
	private Map<Integer, HandlerMethod> handlerMethodMap = new HashMap<>();
	private Map<String, HandlerMethod> dispatcherMappingMap = new HashMap<>();
	public RequestHandlerContext(ApplicationContext context) {
		this.applicationContext = context;
	}
	
	@PostConstruct
	public void init() {
		Map<String, Object> beans = applicationContext.getBeansWithAnnotation(GameMessageHandler.class);
		if(beans != null && beans.size() > 0) {
			beans.values().forEach(obj->{
				Method[] methods = obj.getClass().getMethods();
				if(methods != null) {
					for(Method method : methods) {
						GameMessageMapping gameMessageMapping = method.getAnnotation(GameMessageMapping.class);
						if(gameMessageMapping != null) {
							Class<? extends IGameMessage> clazz = gameMessageMapping.value();
							GameMessageMetaData gameMetadata = clazz.getAnnotation(GameMessageMetaData.class);
							int id = gameMetadata.messageId();
							gameMessageClassMap.put(id, clazz);
							HandlerMethod handlerMethod = new HandlerMethod(obj, method);
							handlerMethodMap.put(id, handlerMethod);
							this.dispatcherMappingMap.put(clazz.getName(), handlerMethod);
							log.debug("加载MessageHandler类：{}, 处理消息：{}的方法",method.getName(), method.getName());
						}
					}
				}
			});
		}
	}
	
	public IGameMessage getRequestMessage(int messageId) {
		Class<? extends IGameMessage> value = this.gameMessageClassMap.get(messageId);
		if(value != null) {
			try {
				return value.newInstance();
			} catch (InstantiationException | IllegalAccessException e) {
				log.error("获取请求消息 实例失败",e);
				return null;
			}
		}
		return null;
	}
	
	public  HandlerMethod getHandlerMethod(int messageId) {
		return this.handlerMethodMap.get(messageId);
	}

    public HandlerMethod getHandlerMethod(IGameMessage gameMessage) {
        return dispatcherMappingMap.get(gameMessage.getClass().getName());
    }
}
